/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package L;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author admin
 */
public class Stopwatch {
    private String name;
    private long startTime = -1;
    private long stopTime = -1;
    private long stoppedTime = 0;
    private boolean running =false;
    private List<Long> stoppedTimes = new ArrayList<Long>(2);
    
    public Stopwatch() {
    }

    public Stopwatch(String name) {
        this.name = name;
    }

    public Stopwatch start() {
        startTime = System.nanoTime();
//        L.d("stopwatch "+name + " started");
        running=true;
        return this;
    }

    public Stopwatch stop() {
        stopTime = System.nanoTime();
        running=false;
        stoppedTime= (stopTime - startTime);
        startTime=-1;
        stoppedTimes.add(stoppedTime);
        return this;
    }

    public Stopwatch reset() {
        startTime = -1;
        stopTime = -1;
        stoppedTimes.clear();
        stoppedTime = 0;
        return this;
    }

    public String getName() {
        return name;
    }

    final static long MILLISECOND = 1000 * 1000;
    final static long SECOND = 1000 * MILLISECOND;
    final static long MINUTE = 60 * SECOND;
    final static long HOUR = 60 * MINUTE;
    final static long DAY = 24 * HOUR;
    
    public long getTotal() {
        long sum=0;
        for (Long st : stoppedTimes) {
            sum+=st;
        }
        return sum;
    }
    
    public long getAverage() {
        return Math.round(this.getTotal()/stoppedTimes.size());
    }
    
    public String printTotal() {
        return "total time stopped over "+stoppedTimes.size()+" executions: "+timeFormat(getTotal());
    }
    
    public String printAverage() {
        return "average over "+stoppedTimes.size()+" stopped executions: "+timeFormat(getAverage());
    }
    
    public static String timeFormat(long t) {
        StringBuffer ret = new StringBuffer();
        if (t - DAY > 0) {
            int days = (int) Math.floor(t / DAY);
            t = t - days * DAY;
            ret.append(days + "d ");
        }
        if (t - HOUR > 0) {
            int hours = (int) Math.floor(t / HOUR);
            t = t - hours * HOUR;
            ret.append(hours + "h ");
        }
        if (t - MINUTE > 0) {
            int mins = (int) Math.floor(t / MINUTE);
            t = t - mins * MINUTE;
            ret.append(mins + "m ");
        }
        if (t - SECOND > 0) {
            int ss = (int) Math.floor(t / SECOND);
            t = t - ss * SECOND;
            ret.append(ss + "s ");
        }
        if (t - MILLISECOND > 0) {
            int ms = (int) Math.floor(t / MILLISECOND);
            t = t - ms * MILLISECOND;
            ret.append(ms + "ms ");
        }
        ret.append(t + "ns");
        return ret.toString();
    }

    @Override
    public String toString() {
        if (!this.isRunning()) {
            return "Stopwatch " + this.name + " : " + timeFormat(getTotalTime());
        } else {
            return "Stopwatched not stopped yet, startTime: " + startTime;
        }
    }

    @Override
    public boolean equals(Object obj) {
        return ((Stopwatch) obj).name.equals(this.name);
    }

    public boolean isRunning() {
        return running;
    }

    private long getTotalTime() {
        long ret=0;
        for (Long t : stoppedTimes) {
            ret+=t;
        }
        return ret;
    }
}
